package com.fujimana.rockincat.restree.text.xml;

import java.beans.Introspector;
import java.io.ByteArrayOutputStream;
import java.util.Locale;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;

import com.fujimana.rockincat.restree.annotation.mime.MimeType;
import com.fujimana.rockincat.restree.converter.Converter;
import com.fujimana.rockincat.restree.exception.InternalServerException;
import com.fujimana.rockincat.restree.util.HttpUtils.HttpStatusCode;

@MimeType(type="text/xml")
public class XMLConverter implements Converter {
	

    @SuppressWarnings("unchecked")
    @Override
    public byte[] format(Object o, Locale locale, String charset) {
            Object jaxbObject = o;
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            
            Class<?> clazz = o.getClass();
            jaxbObject = new JAXBElement(new QName(inferName(clazz)),clazz,jaxbObject);
            
            try {
                    JAXBContext context = JAXBContext.newInstance(o.getClass());
                    Marshaller marshaller = context.createMarshaller();
                    
                    marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
                    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                    marshaller.marshal(jaxbObject, bao);
            } catch (JAXBException e) {
                    throw new InternalServerException(HttpStatusCode.INTERNAL_SERVER_ERROR, e);
            }
            
            return bao.toByteArray();
    }
    
    private static String inferName(Class<?> clazz) {
        return Introspector.decapitalize(clazz.getSimpleName());
    }
}
